package cn.buk.tms.eotms.security;

import cn.buk.common.util.VerifyCodeUtil;
import cn.buk.tms.eotms.entity.User;
import cn.buk.tms.eotms.service.UserService;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 *
 * @author yfdai
 * @date 2016-12-28
 */
@Service
public class MyUserDetailsServiceImpl implements UserDetailsService {

    private static final Logger logger = LogManager.getLogger(MyUserDetailsServiceImpl.class);

    private final UserService userService;

    private final PasswordEncoder passwordEncoder; //= new BCryptPasswordEncoder();

    public MyUserDetailsServiceImpl(UserService userService,
                                    PasswordEncoder passwordEncoder) {
        this.userService = userService;
        this.passwordEncoder = passwordEncoder;
    }


    /**
     * mvc中如果有/login处理代码，则此处不会被触发(不启用 http.formLogin())
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {

        User user = userService.getUserByUsername(username);

        if (user != null) {
            List<GrantedAuthority> authorities = new ArrayList<>();
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));

            if (user.getEnterpriseId() == user.getId()) {
                authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
                logger.info("{} is administrator.", username);
            }

            Set<String> roles = userService.loadRolesByUserId(user.getEnterpriseId(), user.getId());
            for (String authority : roles) {
                authorities.add(new SimpleGrantedAuthority(authority));
            }

            final String md5pwd = user.getMd5Password() == null ? VerifyCodeUtil.MD5(user.getPassword()) : user.getMd5Password();
            var pwd1 = passwordEncoder.encode(md5pwd);

            logger.info("user.getMd5Password(): {}.", user.getMd5Password());
            logger.info("Username: {}, password: {}, {}, {}.", user.getUsername(), user.getPassword(), pwd1, authorities.toString());

            return new org.springframework.security.core.userdetails.User(
                    user.getUsername(),
                    pwd1,
                    authorities);
        }

        throw new UsernameNotFoundException(username + " is not found.");
    }

}
